package code_generate

import (
	"fmt"
	"gorm.io/driver/mysql"
	"gorm.io/gorm"
	"os"
	"os/user"
	"strings"
)

type CodeGenConfig struct {
	TableName     string   `gorm:"column:TABLE_NAME"`
	TableComment  string   `gorm:"column:TABLE_COMMENT"`
	Fields        []Fields `gorm:"-"`
	StandardTable bool     `gorm:"-"`
	TargetPath    string   `gorm:"-"`
}

type Fields struct {
	FieldName    string `gorm:"column:COLUMN_NAME"`
	FieldType    string `gorm:"column:DATA_TYPE"`
	FieldComment string `gorm:"column:COLUMN_COMMENT"`
}

// GetCfg 获取配置
func GetCfg(dsn string, tableName string) *CodeGenConfig {
	cfg := &CodeGenConfig{}
	// 获取当前用户
	u, _ := user.Current()
	cfg.TargetPath = u.HomeDir + "/temp/code_generate"
	_ = os.RemoveAll(cfg.TargetPath)
	d, err := gorm.Open(mysql.Open(dsn), &gorm.Config{})
	if err != nil {
		fmt.Println("open mysql failed,", err)
	}
	d.Raw("SELECT TABLE_NAME, TABLE_COMMENT FROM `information_schema`.`TABLES` WHERE `TABLE_SCHEMA` = DATABASE () AND TABLE_NAME = ?", tableName).First(cfg)
	if cfg.TableName != "" {
		fields := make([]Fields, 0)
		d.Raw("SELECT COLUMN_NAME,DATA_TYPE,COLUMN_COMMENT FROM `information_schema`.`COLUMNS` WHERE `TABLE_SCHEMA` = DATABASE() AND `TABLE_NAME` = ? ORDER BY ORDINAL_POSITION", tableName).Find(&fields)
		if len(fields) > 0 {
			cfg.Fields = fields
			id, cu, ct, uu, ut := false, false, false, false, false
			for _, field := range fields {
				if field.FieldName == "id" {
					id = true
				} else if field.FieldName == "creator_id" {
					cu = true
				} else if field.FieldName == "create_time" {
					ct = true
				} else if field.FieldName == "modifier_id" {
					uu = true
				} else if field.FieldName == "modified_time" {
					ut = true
				}
			}
			if id && cu && ct && uu && ut {
				cfg.StandardTable = true
			}
		}
	}
	return cfg
}

// GenPO 生成PO
func GenPO(cfg *CodeGenConfig, packageName string, sys bool) string {
	result := ""
	if sys {
		result += fmt.Sprintf("type %s struct {", BigHump(cfg.TableName))
		result += fmt.Sprintf("\n")
		if cfg.StandardTable {
			result += fmt.Sprintf("\tcommon_models.PrimaryKey")
			result += fmt.Sprintf("\n")
		}

		for _, field := range cfg.Fields {
			if cfg.StandardTable && (field.FieldName == "id" || field.FieldName == "creator_id" || field.FieldName == "create_time" || field.FieldName == "modifier_id" || field.FieldName == "modified_time") {
				continue
			}
			result += fmt.Sprintf("\t%s %s `json:\"%s\" gorm:\"column:%s\" comment:\"%s\"`", BigHump(field.FieldName), GoLangTypeMapping(field.FieldName, field.FieldType), SmallHump(field.FieldName), field.FieldName, field.FieldComment)
			result += "\n"
		}
		if cfg.StandardTable {
			result += fmt.Sprintf("\tcommon_models.ControlBy")
			result += fmt.Sprintf("\n")
			result += fmt.Sprintf("\tcommon_models.ModelTime")
			result += fmt.Sprintf("\n")
		}
		result += fmt.Sprintf("\tcommon_models.Page")
		result += fmt.Sprintf("\n")
		result += fmt.Sprintf("}\n")
		result += fmt.Sprintf("\n")
		result += fmt.Sprintf("func (%s) TableName() string {", BigHump(cfg.TableName))
		result += fmt.Sprintf("\n")
		result += fmt.Sprintf("\treturn \"%s\"", cfg.TableName)
		result += fmt.Sprintf("\n")
		result += fmt.Sprintf("}")
		WriteFile(result, cfg.TargetPath+"/sys/models/"+packageName, "po.go")
	} else {
		result += fmt.Sprintf("type %s struct {", BigHump(cfg.TableName))
		result += fmt.Sprintf("\n")
		if cfg.StandardTable {
			result += fmt.Sprintf("\tcommon_models.PrimaryKey")
			result += fmt.Sprintf("\n")
		}

		for _, field := range cfg.Fields {
			if cfg.StandardTable && (field.FieldName == "id" || field.FieldName == "create_time" || field.FieldName == "modified_time") {
				continue
			}
			result += fmt.Sprintf("\t%s %s `json:\"%s\" gorm:\"column:%s\" comment:\"%s\"`", BigHump(field.FieldName), GoLangTypeMapping(field.FieldName, field.FieldType), SmallHump(field.FieldName), field.FieldName, field.FieldComment)
			result += "\n"
		}
		if cfg.StandardTable {
			result += fmt.Sprintf("\tcommon_models.ModelTime")
			result += fmt.Sprintf("\n")
		}
		result += fmt.Sprintf("}")
		result += fmt.Sprintf("\n")
		result += fmt.Sprintf("func (%s) TableName() string {", BigHump(cfg.TableName))
		result += fmt.Sprintf("\n")
		result += fmt.Sprintf("\treturn \"%s\"", cfg.TableName)
		result += fmt.Sprintf("\n")
		result += fmt.Sprintf("}")
		WriteFile(result, cfg.TargetPath+"/bs/models/"+packageName, "po.go")
	}
	return result
}

// GenDao 生成Dao
func GenDao(cfg *CodeGenConfig, packageName string, sys bool) string {
	result := ""
	if sys {
		result += fmt.Sprintf("package dao\n")
		result += fmt.Sprintf("\n")
		result += fmt.Sprintf("import (\n")
		result += fmt.Sprintf("\tmodels \"app/models/%s\"\n", packageName)
		result += fmt.Sprintf("\t\"gitee.com/xlizy/common-go/base/enums/common_error\"\n")
		if ExistStatusField(cfg) {
			result += fmt.Sprintf("\t\"gitee.com/xlizy/common-go/base/enums/enabled\"\n")
		}
		result += fmt.Sprintf("\t\"gitee.com/xlizy/common-go/base/response\"\n")
		result += fmt.Sprintf("\t\"gitee.com/xlizy/common-go/components/orm\"\n")
		if ExistStatusField(cfg) {
			result += fmt.Sprintf("\t\"time\"\n")
		}
		result += fmt.Sprintf(")\n")
		result += fmt.Sprintf("\n")
		result += fmt.Sprintf("type %sDao struct {}\n", BigHump(cfg.TableName))
		result += fmt.Sprintf("\n")
		result += fmt.Sprintf("func (d %sDao) Page(query *models.%s) *response.PageResponse {\n", BigHump(cfg.TableName), BigHump(cfg.TableName))
		result += fmt.Sprintf("\tentity := models.%s{}\n", BigHump(cfg.TableName))
		result += fmt.Sprintf("\tresult := make([]models.%s, 0)\n", BigHump(cfg.TableName))
		result += fmt.Sprintf("\tvar totalRows int64 = 0\n")
		result += fmt.Sprintf("\tdb := orm.ConnMulti(DS).Table(entity.TableName())\n")
		result += fmt.Sprintf("\terr := db.Count(&totalRows).Limit(query.GetLimit()).Offset(query.GetOffset()).Find(&result).Error\n")
		result += fmt.Sprintf("\tif err != nil {\n")
		result += fmt.Sprintf("\t\torm.ErrHandler(err)\n")
		result += fmt.Sprintf("\t}\n")
		result += fmt.Sprintf("\treturn response.Page(totalRows, &result, query.PageNum, query.PageSize, query.PageNum, query.PageSize)\n")
		result += fmt.Sprintf("}\n")
		result += fmt.Sprintf("\n")
		result += fmt.Sprintf("func (d %sDao) GetById(id string) *models.%s {\n", BigHump(cfg.TableName), BigHump(cfg.TableName))
		result += fmt.Sprintf("\tentity := &models.%s{}\n", BigHump(cfg.TableName))
		result += fmt.Sprintf("\terr := orm.ConnMulti(DS).Table(entity.TableName()).Where(\"id = ?\", id).First(entity).Error\n")
		result += fmt.Sprintf("\tif err != nil {\n")
		result += fmt.Sprintf("\t\torm.ErrHandler(err)\n")
		result += fmt.Sprintf("\t}\n")
		result += fmt.Sprintf("\treturn entity\n")
		result += fmt.Sprintf("}\n")
		result += fmt.Sprintf("\n")
		result += fmt.Sprintf("func (d %sDao) Add(entity *models.%s) *response.Response {\n", BigHump(cfg.TableName), BigHump(cfg.TableName))
		result += fmt.Sprintf("\tdb := orm.ConnMulti(DS).Create(entity)\n")
		result += fmt.Sprintf("\terr := db.Error\n")
		result += fmt.Sprintf("\tif err != nil {\n")
		result += fmt.Sprintf("\t\treturn orm.ErrHandler(err)\n")
		result += fmt.Sprintf("\t}\n")
		result += fmt.Sprintf("\tif db.RowsAffected > 0 {\n")
		result += fmt.Sprintf("\t\treturn response.SuccMsg(\"保存成功\")\n")
		result += fmt.Sprintf("\t} else {\n")
		result += fmt.Sprintf("\t\treturn response.Error(common_error.RowsAffectedZero, nil)\n")
		result += fmt.Sprintf("\t}\n")
		result += fmt.Sprintf("}\n")
		result += fmt.Sprintf("\n")
		result += fmt.Sprintf("func (d %sDao) Edit(entity *models.%s) *response.Response {\n", BigHump(cfg.TableName), BigHump(cfg.TableName))
		result += fmt.Sprintf("\tdb := orm.ConnMulti(DS).Select(\"*\").Updates(entity)\n")
		result += fmt.Sprintf("\terr := db.Error\n")
		result += fmt.Sprintf("\tif err != nil {\n")
		result += fmt.Sprintf("\t\treturn orm.ErrHandler(err)\n")
		result += fmt.Sprintf("\t}\n")
		result += fmt.Sprintf("\tif db.RowsAffected > 0 {\n")
		result += fmt.Sprintf("\t\treturn response.SuccMsg(\"修改成功\")\n")
		result += fmt.Sprintf("\t} else {\n")
		result += fmt.Sprintf("\t\treturn response.Error(common_error.RowsAffectedZero, nil)\n")
		result += fmt.Sprintf("\t}\n")
		result += fmt.Sprintf("}\n")
		result += fmt.Sprintf("\n")
		result += fmt.Sprintf("func (d %sDao) DelById(id string) *response.Response {\n", BigHump(cfg.TableName))
		result += fmt.Sprintf("\tentity := &models.%s{}\n", BigHump(cfg.TableName))
		result += fmt.Sprintf("\tdb := orm.ConnMulti(DS).Where(\"id = ?\", id).Delete(entity)\n")
		result += fmt.Sprintf("\terr := db.Error\n")
		result += fmt.Sprintf("\tif err != nil {\n")
		result += fmt.Sprintf("\t\treturn orm.ErrHandler(err)\n")
		result += fmt.Sprintf("\t}\n")
		result += fmt.Sprintf("\tif db.RowsAffected > 0 {\n")
		result += fmt.Sprintf("\t\treturn response.SuccMsg(\"删除成功\")\n")
		result += fmt.Sprintf("\t} else {\n")
		result += fmt.Sprintf("\t\treturn response.Error(common_error.RowsAffectedZero, nil)\n")
		result += fmt.Sprintf("\t}\n")
		result += fmt.Sprintf("}\n")
		result += fmt.Sprintf("\n")
		if ExistStatusField(cfg) {
			result += fmt.Sprintf("func (d %sDao) Enable(id, modifierId string) *response.Response {\n", BigHump(cfg.TableName))
			result += fmt.Sprintf("\tentity := models.%s{}\n", BigHump(cfg.TableName))
			result += fmt.Sprintf("\tev := map[string]interface{}{\n")
			result += fmt.Sprintf("\t\t\"status\":        enabled.True,\n")
			result += fmt.Sprintf("\t\t\"modified_time\": time.Now(),\n")
			result += fmt.Sprintf("\t\t\"modifier_id\":   modifierId,\n")
			result += fmt.Sprintf("\t}\n")
			result += fmt.Sprintf("\tdb := orm.ConnMulti(DS).Table(entity.TableName()).Where(\"id = ? and status != ?\", id, enabled.True).Updates(ev)\n")
			result += fmt.Sprintf("\terr := db.Error\n")
			result += fmt.Sprintf("\tif err != nil {\n")
			result += fmt.Sprintf("\t\treturn orm.ErrHandler(err)\n")
			result += fmt.Sprintf("\t}\n")
			result += fmt.Sprintf("\tif db.RowsAffected > 0 {\n")
			result += fmt.Sprintf("\t\treturn response.SuccMsg(\"启用成功\")\n")
			result += fmt.Sprintf("\t} else {\n")
			result += fmt.Sprintf("\t\treturn response.Error(common_error.RowsAffectedZero, nil)\n")
			result += fmt.Sprintf("\t}\n")
			result += fmt.Sprintf("}\n")
			result += fmt.Sprintf("\n")
			result += fmt.Sprintf("func (d %sDao) DisEnable(id, modifierId string) *response.Response {\n", BigHump(cfg.TableName))
			result += fmt.Sprintf("\tentity := models.%s{}\n", BigHump(cfg.TableName))
			result += fmt.Sprintf("\tev := map[string]interface{}{\n")
			result += fmt.Sprintf("\t\t\"status\":        enabled.False,\n")
			result += fmt.Sprintf("\t\t\"modified_time\": time.Now(),\n")
			result += fmt.Sprintf("\t\t\"modifier_id\":   modifierId,\n")
			result += fmt.Sprintf("\t}\n")
			result += fmt.Sprintf("\tdb := orm.ConnMulti(DS).Table(entity.TableName()).Where(\"id = ? and status != ?\", id, enabled.False).Updates(ev)\n")
			result += fmt.Sprintf("\terr := db.Error\n")
			result += fmt.Sprintf("\tif err != nil {\n")
			result += fmt.Sprintf("\t\treturn orm.ErrHandler(err)\n")
			result += fmt.Sprintf("\t}\n")
			result += fmt.Sprintf("\tif db.RowsAffected > 0 {\n")
			result += fmt.Sprintf("\t\treturn response.SuccMsg(\"禁用成功\")\n")
			result += fmt.Sprintf("\t} else {\n")
			result += fmt.Sprintf("\t\treturn response.Error(common_error.RowsAffectedZero, nil)\n")
			result += fmt.Sprintf("\t}\n")
			result += fmt.Sprintf("}\n")
			result += fmt.Sprintf("\n")
		}
		WriteFile(result, cfg.TargetPath+"/sys/dao/"+packageName, cfg.TableName+"_dao.go")
	} else {
		result += fmt.Sprintf("package dao\n")
		result += fmt.Sprintf("\n")
		result += fmt.Sprintf("import (\n")
		result += fmt.Sprintf("\t\"app/models\"\n")
		result += fmt.Sprintf(")\n")
		result += fmt.Sprintf("\n")
		result += fmt.Sprintf("type %sDao struct {}\n", BigHump(cfg.TableName))
		result += fmt.Sprintf("\n")
		WriteFile(result, cfg.TargetPath+"/bs/dao/"+packageName, cfg.TableName+"_dao.go")
	}

	return result
}

// GenService 生成Service
func GenService(cfg *CodeGenConfig, packageName string, sys bool) string {
	result := ""
	if sys {
		result += fmt.Sprintf("package service\n")
		result += fmt.Sprintf("\n")
		result += fmt.Sprintf("import (\n")
		result += fmt.Sprintf("\tdao \"app/dao/%s\"\n", packageName)
		result += fmt.Sprintf("\tmodels \"app/models/%s\"\n", packageName)
		result += fmt.Sprintf("\t\"gitee.com/xlizy/common-go/base/response\"\n")
		result += fmt.Sprintf("\t\"gitee.com/xlizy/common-go/utils/snowflake\"\n")
		result += fmt.Sprintf("\t\"gitee.com/xlizy/common-go/utils/threadlocal\"\n")
		result += fmt.Sprintf("\t\"gitee.com/xlizy/common-go/utils/zlog\"\n")
		result += fmt.Sprintf("\t\"time\"\n")
		result += fmt.Sprintf(")\n")
		result += fmt.Sprintf("\n")
		result += fmt.Sprintf("type %sService struct {\n}\n", BigHump(cfg.TableName))
		result += fmt.Sprintf("\n")
		result += fmt.Sprintf("func (s %sService) Page(e *models.%s) *response.PageResponse {\n", BigHump(cfg.TableName), BigHump(cfg.TableName))
		result += fmt.Sprintf("\td := dao.%sDao{}\n", BigHump(cfg.TableName))
		result += fmt.Sprintf("\treturn d.Page(e)\n")
		result += fmt.Sprintf("}\n")
		result += fmt.Sprintf("\n")
		result += fmt.Sprintf("func (s %sService) Add(e *models.%s) *response.Response {\n", BigHump(cfg.TableName), BigHump(cfg.TableName))
		result += fmt.Sprintf("\tzlog.Info(\"添加对象:{}\", json.ToJsonStr(e))\n")
		result += fmt.Sprintf("\td := dao.%sDao{}\n", BigHump(cfg.TableName))
		result += fmt.Sprintf("\te.Id = snowflake.NextId()\n")
		result += fmt.Sprintf("\te.CreateTime.Time = time.Now()\n")
		result += fmt.Sprintf("\te.CreatorId = threadlocal.GetUserId()\n")
		result += fmt.Sprintf("\treturn d.Add(e)\n")
		result += fmt.Sprintf("}\n")
		result += fmt.Sprintf("\n")
		result += fmt.Sprintf("func (s %sService) Edit(e *models.%s) *response.Response {\n", BigHump(cfg.TableName), BigHump(cfg.TableName))
		result += fmt.Sprintf("\tzlog.Info(\"修改对象:{}\", json.ToJsonStr(e))\n")
		result += fmt.Sprintf("\td := dao.%sDao{}\n", BigHump(cfg.TableName))
		result += fmt.Sprintf("\te.ModifiedTime.Time = time.Now()\n")
		result += fmt.Sprintf("\te.ModifierId = threadlocal.GetUserId()\n")
		result += fmt.Sprintf("\treturn d.Edit(e)\n")
		result += fmt.Sprintf("}\n")
		result += fmt.Sprintf("\n")
		result += fmt.Sprintf("func (s %sService) GetById(id string) *response.Response {\n", BigHump(cfg.TableName))
		result += fmt.Sprintf("\td := dao.%sDao{}\n", BigHump(cfg.TableName))
		result += fmt.Sprintf("\te := d.GetById(id)\n")
		result += fmt.Sprintf("\tif e.Id != \"\" {\n")
		result += fmt.Sprintf("\t\treturn response.Success(\"获取成功\", e)\n")
		result += fmt.Sprintf("\t} else {\n")
		result += fmt.Sprintf("\t\treturn response.Error(common_error.DataNotExist, nil)\n")
		result += fmt.Sprintf("\t}\n")
		result += fmt.Sprintf("}\n")
		result += fmt.Sprintf("\n")
		result += fmt.Sprintf("func (s %sService) Del(id string) *response.Response {\n", BigHump(cfg.TableName))
		result += fmt.Sprintf("\tzlog.Info(\"id:{}\", id)\n")
		result += fmt.Sprintf("\td := dao.%sDao{}\n", BigHump(cfg.TableName))
		result += fmt.Sprintf("\treturn d.DelById(id)\n")
		result += fmt.Sprintf("}\n")
		result += fmt.Sprintf("\n")
		if ExistStatusField(cfg) {
			result += fmt.Sprintf("\n")
			result += fmt.Sprintf("func (s %sService) Enable(id string) *response.Response {\n", BigHump(cfg.TableName))
			result += fmt.Sprintf("\tzlog.Info(\"id:{}\", id)\n")
			result += fmt.Sprintf("\td := dao.%sDao{}\n", BigHump(cfg.TableName))
			result += fmt.Sprintf("\treturn d.Enable(id, threadlocal.GetUserId())\n")
			result += fmt.Sprintf("}\n")
			result += fmt.Sprintf("\n")
			result += fmt.Sprintf("func (s %sService) DisEnable(id string) *response.Response {\n", BigHump(cfg.TableName))
			result += fmt.Sprintf("\tzlog.Info(\"id:{}\", id)\n")
			result += fmt.Sprintf("\td := dao.%sDao{}\n", BigHump(cfg.TableName))
			result += fmt.Sprintf("\treturn d.DisEnable(id, threadlocal.GetUserId())\n")
			result += fmt.Sprintf("}\n")
			result += fmt.Sprintf("\n")
		}
		WriteFile(result, cfg.TargetPath+"/sys/service/"+packageName, cfg.TableName+"_service.go")
	} else {
		result += fmt.Sprintf("package service\n")
		result += fmt.Sprintf("\n")
		result += fmt.Sprintf("import (\n")
		result += fmt.Sprintf("\t\"app/dao\"\n")
		result += fmt.Sprintf("\t\"app/models\"\n")
		result += fmt.Sprintf(")\n")
		result += fmt.Sprintf("\n")
		result += fmt.Sprintf("type %sService struct {\n}\n", BigHump(cfg.TableName))
		result += fmt.Sprintf("\n")
		WriteFile(result, cfg.TargetPath+"/bs/service/"+packageName, cfg.TableName+"_service.go")
	}

	return result
}

// GenController 生成Controller
func GenController(cfg *CodeGenConfig, packageName string, sys bool) string {
	result := ""
	if sys {
		result += fmt.Sprintf("package %s\n", packageName)
		result += fmt.Sprintf("\n")
		result += fmt.Sprintf("import (\n")
		result += fmt.Sprintf("\tmodels \"app/models/%s\"\n", packageName)
		result += fmt.Sprintf("\tservice \"app/service/%s\"\n", packageName)
		result += fmt.Sprintf("\t\"gitee.com/xlizy/common-go/utils/validator\"\n")
		result += fmt.Sprintf("\t\"github.com/kataras/iris/v12\"\n")
		result += fmt.Sprintf("\t\"google.golang.org/genproto/protobuf/api\"\n")
		result += fmt.Sprintf(")\n")
		result += fmt.Sprintf("\n")
		result += fmt.Sprintf("type %sController struct {\n", BigHump(cfg.TableName))
		result += fmt.Sprintf("\tapi.Api\n")
		result += fmt.Sprintf("}\n")
		result += fmt.Sprintf("\n")
		result += fmt.Sprintf("func (c *%sController) Page(ctx iris.Context) {\n", BigHump(cfg.TableName))
		result += fmt.Sprintf("\ts := service.%sService{}\n", BigHump(cfg.TableName))
		result += fmt.Sprintf("\treq := &models.%s{}\n", BigHump(cfg.TableName))
		result += fmt.Sprintf("\t_ = ctx.ReadJSON(req)\n")
		result += fmt.Sprintf("\t_ = ctx.JSON(s.Page(req))\n")
		result += fmt.Sprintf("}\n")
		result += fmt.Sprintf("\n")
		result += fmt.Sprintf("func (c *%sController) Add(ctx iris.Context) {\n", BigHump(cfg.TableName))
		result += fmt.Sprintf("\ts := service.%sService{}\n", BigHump(cfg.TableName))
		result += fmt.Sprintf("\treq := &models.%s{}\n", BigHump(cfg.TableName))
		result += fmt.Sprintf("\t_ = ctx.ReadJSON(req)\n")
		result += fmt.Sprintf("\tif cp := validator.ValidParams(req); cp.Success {\n")
		result += fmt.Sprintf("\t\t_ = ctx.JSON(s.Add(req))\n")
		result += fmt.Sprintf("\t} else {\n")
		result += fmt.Sprintf("\t\t_ = ctx.JSON(cp)\n")
		result += fmt.Sprintf("\t}\n")
		result += fmt.Sprintf("}\n")
		result += fmt.Sprintf("\n")
		result += fmt.Sprintf("func (c *%sController) Edit(ctx iris.Context) {\n", BigHump(cfg.TableName))
		result += fmt.Sprintf("\ts := service.%sService{}\n", BigHump(cfg.TableName))
		result += fmt.Sprintf("\treq := &models.%s{}\n", BigHump(cfg.TableName))
		result += fmt.Sprintf("\t_ = ctx.ReadJSON(req)\n")
		result += fmt.Sprintf("\tif cp := validator.ValidParams(req); cp.Success {\n")
		result += fmt.Sprintf("\t\t_ = ctx.JSON(s.Edit(req))\n")
		result += fmt.Sprintf("\t} else {\n")
		result += fmt.Sprintf("\t\t_ = ctx.JSON(cp)\n")
		result += fmt.Sprintf("\t}\n")
		result += fmt.Sprintf("}\n")
		result += fmt.Sprintf("\n")
		result += fmt.Sprintf("func (c *%sController) GetById(ctx iris.Context) {\n", BigHump(cfg.TableName))
		result += fmt.Sprintf("\ts := service.%sService{}\n", BigHump(cfg.TableName))
		result += fmt.Sprintf("\tid := ctx.Params().Get(\"id\")\n")
		result += fmt.Sprintf("\t_ = ctx.JSON(s.GetById(id))\n")
		result += fmt.Sprintf("}\n")
		result += fmt.Sprintf("\n")
		result += fmt.Sprintf("func (c *%sController) Del(ctx iris.Context) {\n", BigHump(cfg.TableName))
		result += fmt.Sprintf("\ts := service.%sService{}\n", BigHump(cfg.TableName))
		result += fmt.Sprintf("\tid := ctx.Params().Get(\"id\")\n")
		result += fmt.Sprintf("\t_ = ctx.JSON(s.Del(id))\n")
		result += fmt.Sprintf("}\n")
		result += fmt.Sprintf("\n")
		if ExistStatusField(cfg) {
			result += fmt.Sprintf("func (c *%sController) Enable(ctx iris.Context) {\n", BigHump(cfg.TableName))
			result += fmt.Sprintf("\ts := service.%sService{}\n", BigHump(cfg.TableName))
			result += fmt.Sprintf("\tid := ctx.Params().Get(\"id\")\n")
			result += fmt.Sprintf("\t_ = ctx.JSON(s.Enable(id))\n")
			result += fmt.Sprintf("}\n")
			result += fmt.Sprintf("\n")
			result += fmt.Sprintf("func (c *%sController) DisEnable(ctx iris.Context) {\n", BigHump(cfg.TableName))
			result += fmt.Sprintf("\ts := service.%sService{}\n", BigHump(cfg.TableName))
			result += fmt.Sprintf("\tid := ctx.Params().Get(\"id\")\n")
			result += fmt.Sprintf("\t_ = ctx.JSON(s.DisEnable(id))\n")
			result += fmt.Sprintf("}\n")
			result += fmt.Sprintf("\n")
		}
		WriteFile(result, cfg.TargetPath+"/sys/controller/"+packageName, cfg.TableName+"_controller.go")
	} else {
		result += fmt.Sprintf("package controller\n")
		result += fmt.Sprintf("\n")
		result += fmt.Sprintf("import (\n")
		result += fmt.Sprintf("\t\"app/service\"\n")
		result += fmt.Sprintf("\t\"gitee.com/xlizy/common-go/utils/zlog\"\n")
		result += fmt.Sprintf("\t\"github.com/kataras/iris/v12\"\n")
		result += fmt.Sprintf("\t\"google.golang.org/genproto/protobuf/api\"\n")
		result += fmt.Sprintf(")\n")
		result += fmt.Sprintf("\n")
		result += fmt.Sprintf("type %sController struct {\n", BigHump(cfg.TableName))
		result += fmt.Sprintf("\tapi.Api\n")
		result += fmt.Sprintf("}\n")
		result += fmt.Sprintf("\n")
		WriteFile(result, cfg.TargetPath+"/bs/controller/"+packageName, cfg.TableName+"_controller.go")
	}

	return result
}

// GenRouter 生成Router
func GenRouter(cfg *CodeGenConfig, packageName string, sys bool) string {
	result := ""
	if sys {
		result += fmt.Sprintf("%sCtl \"app/controller/%s\"\n", packageName, packageName)
		result += fmt.Sprintf("\n")
		result += fmt.Sprintf("{\n")
		result += fmt.Sprintf("\t%sApi := %sCtl.%sController{}\n", SmallHump(cfg.TableName), packageName, BigHump(cfg.TableName))
		result += fmt.Sprintf("\tgrp, party := rm.BuildGrp(\"/%s\", \"%s\")\n", packageName, cfg.TableComment)
		result += fmt.Sprintf("\trm.AddRouter(grp, party, rm.POST, \"/%s/page\", \"%s列表页查询\", false, %sApi.Page)\n", SmallHump(cfg.TableName), cfg.TableComment, SmallHump(cfg.TableName))
		result += fmt.Sprintf("\trm.AddRouter(grp, party, rm.POST, \"/%s\", \"新增%s\", true, %sApi.Add)\n", SmallHump(cfg.TableName), cfg.TableComment, SmallHump(cfg.TableName))
		result += fmt.Sprintf("\trm.AddRouter(grp, party, rm.PUT, \"/%s\", \"编辑%s信息\", true, %sApi.Edit)\n", SmallHump(cfg.TableName), cfg.TableComment, SmallHump(cfg.TableName))
		result += fmt.Sprintf("\trm.AddRouter(grp, party, rm.GET, \"/%s/{id}\", \"查询%s详情\", false, %sApi.GetById)\n", SmallHump(cfg.TableName), cfg.TableComment, SmallHump(cfg.TableName))
		if ExistStatusField(cfg) {
			result += fmt.Sprintf("\trm.AddRouter(grp, party, rm.PUT, \"/%s/{id}/enable\", \"启用%s\", true, %sApi.Enable)\n", SmallHump(cfg.TableName), cfg.TableComment, SmallHump(cfg.TableName))
			result += fmt.Sprintf("\trm.AddRouter(grp, party, rm.PUT, \"/%s/{id}/disable\", \"禁用%s\", true, %sApi.DisEnable)\n", SmallHump(cfg.TableName), cfg.TableComment, SmallHump(cfg.TableName))
		}
		result += fmt.Sprintf("\trm.AddRouter(grp, party, rm.DELETE, \"/%s/{id}\", \"删除%s\", true, %sApi.Del)\n", SmallHump(cfg.TableName), cfg.TableComment, SmallHump(cfg.TableName))
		result += fmt.Sprintf("}\n")
		WriteFile(result, cfg.TargetPath+"/sys/router", "router.go")
	} else {
		result += fmt.Sprintf("%sCtl \"app/controller/%s\"\n", packageName, packageName)
		result += fmt.Sprintf("\n")
		result += fmt.Sprintf("{\n")
		result += fmt.Sprintf("\t%sApi := %sCtl.%sController{}\n", SmallHump(cfg.TableName), packageName, BigHump(cfg.TableName))
		result += fmt.Sprintf("\tgrp, party := rm.BuildGrp(\"/%s\", \"%s\")\n", packageName, cfg.TableComment)
		result += fmt.Sprintf("\trm.AddRouter(grp, party, rm.GET, \"/xxxx\", \"xxxx\", false, %sApi.GetById)\n", SmallHump(cfg.TableName))
		result += fmt.Sprintf("}\n")
		WriteFile(result, cfg.TargetPath+"/bs/router", "router.go")
		//result += fmt.Sprintf("//%s\n", cfg.TableComment)
		//result += fmt.Sprintf("%sApi := controller.%sController{}\n", SmallHump(cfg.TableName), BigHump(cfg.TableName))
		//result += fmt.Sprintf("%sRouter := r.Party(\"/%s\")\n", SmallHump(cfg.TableName), SmallHump(cfg.TableName))
		//result += fmt.Sprintf("{\n")
		//result += fmt.Sprintf("%sRouter.Post(\"/xxxxx\", %sApi.XXXX)\n", SmallHump(cfg.TableName), SmallHump(cfg.TableName))
		//result += fmt.Sprintf("}\n")
		//result += fmt.Sprintf("\n")
		//WriteFile(result, cfg.TargetPath+"/bs/router", "router.go")
	}

	return result
}

// GenListVue 生成列表页Vue
func GenListVue(cfg *CodeGenConfig, packageName string) string {
	result := ""
	result += fmt.Sprintf("<template>\n")
	result += fmt.Sprintf("\t<a-card :bordered=\"false\" size=\"small\">\n")
	result += fmt.Sprintf("\t\t<div class=\"table-page-search-wrapper\">\n")
	result += fmt.Sprintf("\t\t\t<a-form ref=\"queryFormRef\" :model=\"queryForm\">\n")
	result += fmt.Sprintf("\t\t\t\t<a-row :gutter=\"8\">\n")
	result += fmt.Sprintf("\t\t\t\t\t<a-col :span=\"4\">\n")
	result += fmt.Sprintf("\t\t\t\t\t\t<a-form-item label=\"XXX\" name=\"XXX\">\n")
	result += fmt.Sprintf("\t\t\t\t\t\t\t<a-input v-model:value=\"queryForm.XXX\" size=\"small\" allow-clear />\n")
	result += fmt.Sprintf("\t\t\t\t\t\t</a-form-item>\n")
	result += fmt.Sprintf("\t\t\t\t\t</a-col>\n")
	if ExistStatusField(cfg) {
		result += fmt.Sprintf("\t\t\t\t\t<a-col :span=\"4\">\n")
		result += fmt.Sprintf("\t\t\t\t\t\t<a-form-item label=\"状态\" name=\"status\">\n")
		result += fmt.Sprintf("\t\t\t\t\t\t\t<a-select v-model:value=\"queryForm.status\" size=\"small\" allow-clear>\n")
		result += fmt.Sprintf("\t\t\t\t\t\t\t\t<a-select-option v-for=\"item in statusSelectOptions\" :key=\"item.value\" :value=\"item.value\">\n")
		result += fmt.Sprintf("\t\t\t\t\t\t\t\t\t{{ item.desc }}\n")
		result += fmt.Sprintf("\t\t\t\t\t\t\t\t</a-select-option>\n")
		result += fmt.Sprintf("\t\t\t\t\t\t\t</a-select>\n")
		result += fmt.Sprintf("\t\t\t\t\t\t</a-form-item>\n")
		result += fmt.Sprintf("\t\t\t\t\t</a-col>\n")
	}
	result += fmt.Sprintf("\t\t\t\t\t<a-col :span=\"4\">\n")
	result += fmt.Sprintf("\t\t\t\t\t\t<span class=\"table-page-search-submitButtons\">\n")
	result += fmt.Sprintf("\t\t\t\t\t\t\t<a-button size=\"small\" type=\"primary\" @click=\"table.refresh()\">\n")
	result += fmt.Sprintf("\t\t\t\t\t\t\t\t<template #icon><SearchOutlined /></template>\n")
	result += fmt.Sprintf("\t\t\t\t\t\t\t\t查询\n")
	result += fmt.Sprintf("\t\t\t\t\t\t\t</a-button>\n")
	result += fmt.Sprintf("\t\t\t\t\t\t\t<a-button size=\"small\" style=\"margin-left: 8px\" @click=\"() => queryFormRef.resetFields()\">\n")
	result += fmt.Sprintf("\t\t\t\t\t\t\t\t<template #icon><RollbackOutlined /></template>\n")
	result += fmt.Sprintf("\t\t\t\t\t\t\t\t重置\n")
	result += fmt.Sprintf("\t\t\t\t\t\t\t</a-button>\n")
	result += fmt.Sprintf("\t\t\t\t\t\t</span>\n")
	result += fmt.Sprintf("\t\t\t\t\t</a-col>\n")
	result += fmt.Sprintf("\t\t\t\t</a-row>\n")
	result += fmt.Sprintf("\t\t\t</a-form>\n")
	result += fmt.Sprintf("\t\t</div>\n")
	result += fmt.Sprintf("\t\t<div class=\"table-operator\">\n")
	result += fmt.Sprintf("\t\t\t<a-button type=\"primary\" size=\"small\" @click=\"add\">\n")
	result += fmt.Sprintf("\t\t\t\t<template #icon><FormOutlined /></template>\n")
	result += fmt.Sprintf("\t\t\t\t新建\n")
	result += fmt.Sprintf("\t\t\t</a-button>\n")
	result += fmt.Sprintf("\t\t</div>\n")
	result += fmt.Sprintf("\t\t<x-table ref=\"table\" :url=\"'/sys/%s/%s/page'\" :query-form=\"queryForm\">\n", packageName, SmallHump(cfg.TableName))
	result += fmt.Sprintf("\t\t\t<template #columns>\n")
	result += fmt.Sprintf("\t\t\t\t<vxe-column width=\"160\" field=\"id\" title=\"ID\" fixed=\"left\"></vxe-column>\n")
	result += fmt.Sprintf("\t\t\t\t<vxe-column width=\"200\" field=\"XXX\" title=\"XXX\"></vxe-column>\n")
	if ExistRemarkField(cfg) {
		result += fmt.Sprintf("\t\t\t\t<vxe-column width=\"100\" field=\"remark\" title=\"备注\"></vxe-column>\n")
	}
	if ExistStatusField(cfg) {
		result += fmt.Sprintf("\t\t\t\t<vxe-column width=\"150\" field=\"status\" title=\"状态\">\n")
		result += fmt.Sprintf("\t\t\t\t\t<template #default=\"{ row }\">\n")
		result += fmt.Sprintf("\t\t\t\t\t\t<a-badge v-if=\"row.status && row.status.val === 1\" status=\"success\" :text=\"row.status.des\" />\n")
		result += fmt.Sprintf("\t\t\t\t\t\t<a-badge v-if=\"row.status && row.status.val === 2\" status=\"error\" :text=\"row.status.des\" />\n")
		result += fmt.Sprintf("\t\t\t\t\t</template>\n")
		result += fmt.Sprintf("\t\t\t\t</vxe-column>\n")
	}
	result += fmt.Sprintf("\t\t\t\t<vxe-column width=\"180\" title=\"操作\" fixed=\"right\">\n")
	result += fmt.Sprintf("\t\t\t\t\t<template #default=\"{ row }\">\n")
	result += fmt.Sprintf("\t\t\t\t\t\t<vxe-button type=\"text\" status=\"primary\" size=\"mini\" content=\"修改\" @click=\"edit(row.id)\"></vxe-button>\n")
	if ExistStatusField(cfg) {
		result += fmt.Sprintf("\t\t\t\t\t\t<a-popconfirm v-if=\"row.status.val === 2\" title=\"确定要启用?\" placement=\"topRight\" ok-text=\"确认\" cancel-text=\"取消\" @confirm=\"() => enable(row.id)\">\n")
		result += fmt.Sprintf("\t\t\t\t\t\t\t<vxe-button type=\"text\" status=\"success\" size=\"mini\" content=\"启用\"></vxe-button>\n")
		result += fmt.Sprintf("\t\t\t\t\t\t</a-popconfirm>\n")
		result += fmt.Sprintf("\t\t\t\t\t\t<a-popconfirm v-if=\"row.status.val === 1\" title=\"确定要禁用?\" placement=\"topRight\" ok-text=\"确认\" cancel-text=\"取消\" @confirm=\"() => disable(row.id)\">\n")
		result += fmt.Sprintf("\t\t\t\t\t\t\t<vxe-button type=\"text\" status=\"warning\" size=\"mini\" content=\"禁用\"></vxe-button>\n")
		result += fmt.Sprintf("\t\t\t\t\t\t</a-popconfirm>\n")
	}
	result += fmt.Sprintf("\t\t\t\t\t\t<a-popconfirm title=\"确定要删除?\" placement=\"topRight\" ok-text=\"确认\" cancel-text=\"取消\" @confirm=\"() => del(row.id)\">\n")
	result += fmt.Sprintf("\t\t\t\t\t\t\t<vxe-button type=\"text\" status=\"danger\" size=\"mini\" content=\"删除\"></vxe-button>\n")
	result += fmt.Sprintf("\t\t\t\t\t\t</a-popconfirm>\n")
	result += fmt.Sprintf("\t\t\t\t\t</template>\n")
	result += fmt.Sprintf("\t\t\t\t</vxe-column>\n")
	result += fmt.Sprintf("\t\t\t</template>\n")
	result += fmt.Sprintf("\t\t</x-table>\n")
	result += fmt.Sprintf("\t</a-card>\n")
	result += fmt.Sprintf("\t<%sEditForm ref=\"createModal\" @ok=\"table.refresh()\"></%sEditForm>\n", BigHump(cfg.TableName), BigHump(cfg.TableName))
	result += fmt.Sprintf("</template>\n")
	result += fmt.Sprintf("\n")
	result += fmt.Sprintf("<script>\n")
	result += fmt.Sprintf("import { reactive, ref, inject } from 'vue';\n")
	result += fmt.Sprintf("import %sEditForm from '@/views/%s/modules/%sEditForm.vue';\n", BigHump(cfg.TableName), packageName, BigHump(cfg.TableName))
	result += fmt.Sprintf("import { FormOutlined, RollbackOutlined, SearchOutlined } from '@ant-design/icons-vue';\n")
	result += fmt.Sprintf("\n")
	result += fmt.Sprintf("export default {\n")
	result += fmt.Sprintf("\tcomponents: { RollbackOutlined, SearchOutlined, FormOutlined, %sEditForm },\n", BigHump(cfg.TableName))
	result += fmt.Sprintf("\tsetup(props, context) {\n")
	result += fmt.Sprintf("\t\tconst common = inject('common');\n")
	if ExistStatusField(cfg) {
		result += fmt.Sprintf("\t\tconst statusSelectOptions = ref();\n")
	}
	result += fmt.Sprintf("\t\tconst queryForm = reactive({});\n")
	result += fmt.Sprintf("\t\tconst queryFormRef = ref();\n")
	result += fmt.Sprintf("\t\tconst table = ref();\n")
	result += fmt.Sprintf("\t\tconst createModal = ref();\n")
	result += fmt.Sprintf("\n")
	if ExistStatusField(cfg) {
		result += fmt.Sprintf("\t\tcommon.loadDropdownData(statusSelectOptions, '/sys/system/enabledSelectOptions');\n")
		result += fmt.Sprintf("\n")
	}
	result += fmt.Sprintf("\t\tconst add = () => {\n")
	result += fmt.Sprintf("\t\t\tcreateModal.value.open();\n")
	result += fmt.Sprintf("\t\t};\n")
	result += fmt.Sprintf("\t\tconst edit = dataId => {\n")
	result += fmt.Sprintf("\t\t\tcreateModal.value.open(dataId);\n")
	result += fmt.Sprintf("\t\t};\n")
	if ExistStatusField(cfg) {
		result += fmt.Sprintf("\t\tconst enable = dataId => {\n")
		result += fmt.Sprintf("\t\t\tcommon\n")
		result += fmt.Sprintf("\t\t\t\t.api({\n")
		result += fmt.Sprintf("\t\t\t\t\turl: process.env.MANAGE_GATEWAY_HOST + '/sys/%s/%s/' + dataId + '/enable',\n", packageName, SmallHump(cfg.TableName))
		result += fmt.Sprintf("\t\t\t\t\tmethod: 'put',\n")
		result += fmt.Sprintf("\t\t\t\t})\n")
		result += fmt.Sprintf("\t\t\t\t.then(response => {\n")
		result += fmt.Sprintf("\t\t\t\t\tif (response.success) {\n")
		result += fmt.Sprintf("\t\t\t\t\t\tcommon.msg.success(response.msg);\n")
		result += fmt.Sprintf("\t\t\t\t\t\ttable.value.refresh();\n")
		result += fmt.Sprintf("\t\t\t\t\t} else {\n")
		result += fmt.Sprintf("\t\t\t\t\t\tcommon.msg.warning(response.msg);\n")
		result += fmt.Sprintf("\t\t\t\t\t}\n")
		result += fmt.Sprintf("\t\t\t\t})\n")
		result += fmt.Sprintf("\t\t\t\t.catch(err => {\n")
		result += fmt.Sprintf("\t\t\t\t\tconsole.log(err);\n")
		result += fmt.Sprintf("\t\t\t\t});\n")
		result += fmt.Sprintf("\t\t};\n")
		result += fmt.Sprintf("\t\tconst disable = dataId => {\n")
		result += fmt.Sprintf("\t\t\tcommon\n")
		result += fmt.Sprintf("\t\t\t\t.api({\n")
		result += fmt.Sprintf("\t\t\t\t\turl: process.env.MANAGE_GATEWAY_HOST + '/sys/%s/%s/' + dataId + '/disable',\n", packageName, SmallHump(cfg.TableName))
		result += fmt.Sprintf("\t\t\t\t\tmethod: 'put',\n")
		result += fmt.Sprintf("\t\t\t\t})\n")
		result += fmt.Sprintf("\t\t\t\t.then(response => {\n")
		result += fmt.Sprintf("\t\t\t\t\tif (response.success) {\n")
		result += fmt.Sprintf("\t\t\t\t\t\tcommon.msg.success(response.msg);\n")
		result += fmt.Sprintf("\t\t\t\t\t\ttable.value.refresh();\n")
		result += fmt.Sprintf("\t\t\t\t\t} else {\n")
		result += fmt.Sprintf("\t\t\t\t\t\tcommon.msg.warning(response.msg);\n")
		result += fmt.Sprintf("\t\t\t\t\t}\n")
		result += fmt.Sprintf("\t\t\t\t})\n")
		result += fmt.Sprintf("\t\t\t\t.catch(err => {\n")
		result += fmt.Sprintf("\t\t\t\t\tconsole.log(err);\n")
		result += fmt.Sprintf("\t\t\t\t});\n")
		result += fmt.Sprintf("\t\t};\n")
	}
	result += fmt.Sprintf("\t\tconst del = dataId => {\n")
	result += fmt.Sprintf("\t\t\tcommon\n")
	result += fmt.Sprintf("\t\t\t\t.api({\n")
	result += fmt.Sprintf("\t\t\t\t\turl: process.env.MANAGE_GATEWAY_HOST + '/sys/%s/%s/' + dataId,\n", packageName, SmallHump(cfg.TableName))
	result += fmt.Sprintf("\t\t\t\t\tmethod: 'delete',\n")
	result += fmt.Sprintf("\t\t\t\t})\n")
	result += fmt.Sprintf("\t\t\t\t.then(response => {\n")
	result += fmt.Sprintf("\t\t\t\t\tif (response.success) {\n")
	result += fmt.Sprintf("\t\t\t\t\t\tcommon.msg.success(response.msg);\n")
	result += fmt.Sprintf("\t\t\t\t\t\ttable.value.refresh();\n")
	result += fmt.Sprintf("\t\t\t\t\t} else {\n")
	result += fmt.Sprintf("\t\t\t\t\t\tcommon.msg.warning(response.msg);\n")
	result += fmt.Sprintf("\t\t\t\t\t}\n")
	result += fmt.Sprintf("\t\t\t\t})\n")
	result += fmt.Sprintf("\t\t\t\t.catch(err => {\n")
	result += fmt.Sprintf("\t\t\t\t\tconsole.log(err);\n")
	result += fmt.Sprintf("\t\t\t\t});\n")
	result += fmt.Sprintf("\t\t};\n")
	result += fmt.Sprintf("\t\treturn {\n")
	result += fmt.Sprintf("\t\t\tcommon,\n")
	if ExistStatusField(cfg) {
		result += fmt.Sprintf("\t\t\tstatusSelectOptions,\n")
	}
	result += fmt.Sprintf("\t\t\tqueryForm,\n")
	result += fmt.Sprintf("\t\t\tqueryFormRef,\n")
	result += fmt.Sprintf("\t\t\ttable,\n")
	result += fmt.Sprintf("\t\t\tcreateModal,\n")
	result += fmt.Sprintf("\t\t\tadd,\n")
	result += fmt.Sprintf("\t\t\tedit,\n")
	if ExistStatusField(cfg) {
		result += fmt.Sprintf("\t\t\tenable,\n")
		result += fmt.Sprintf("\t\t\tdisable,\n")
	}
	result += fmt.Sprintf("\t\t\tdel,\n")
	result += fmt.Sprintf("\t\t};\n")
	result += fmt.Sprintf("\t},\n")
	result += fmt.Sprintf("};\n")
	result += fmt.Sprintf("</script>\n")
	result += fmt.Sprintf("\n")
	result += fmt.Sprintf("<style lang=\"less\"></style>\n")
	WriteFile(result, cfg.TargetPath+"/vue/"+packageName, BigHump(cfg.TableName)+"List.vue")
	return result
}

// GenEditVue 生成编辑页Vue
func GenEditVue(cfg *CodeGenConfig, packageName string) string {
	result := ""
	result += fmt.Sprintf("<template>\n")
	result += fmt.Sprintf("\t<a-drawer v-model:open=\"visible\" :title=\"title\" placement=\"right\" :mask-closable=\"false\" width=\"800\" @close=\"handleCancel\">\n")
	result += fmt.Sprintf("\t\t<a-spin :spinning=\"formLoading\">\n")
	result += fmt.Sprintf("\t\t\t<a-form :model=\"defaultForm\">\n")
	result += fmt.Sprintf("\t\t\t\t<a-form-item hidden label=\"id\">\n")
	result += fmt.Sprintf("\t\t\t\t\t<a-input v-model:value=\"defaultForm.id\" />\n")
	result += fmt.Sprintf("\t\t\t\t</a-form-item>\n")
	result += fmt.Sprintf("\t\t\t\t<a-form-item label=\"XXX\" v-bind=\"defaultFormObj.validateInfos.XXX\" :label-col=\"labelCol\" :wrapper-col=\"wrapperCol\">\n")
	result += fmt.Sprintf("\t\t\t\t\t<a-input v-model:value=\"defaultForm.XXX\" maxlength=\"100\" placeholder=\"XXX\" />\n")
	result += fmt.Sprintf("\t\t\t\t</a-form-item>\n")
	if ExistRemarkField(cfg) {
		result += fmt.Sprintf("\t\t\t\t<a-form-item label=\"备注\" v-bind=\"defaultFormObj.validateInfos.remark\" :label-col=\"labelCol\" :wrapper-col=\"wrapperCol\">\n")
		result += fmt.Sprintf("\t\t\t\t\t<a-input v-model:value=\"defaultForm.remark\" maxlength=\"100\" placeholder=\"备注\" />\n")
		result += fmt.Sprintf("\t\t\t\t</a-form-item>\n")
	}
	result += fmt.Sprintf("\t\t\t</a-form>\n")
	result += fmt.Sprintf("\t\t\t<a-divider />\n")
	result += fmt.Sprintf("\t\t\t<a-alert v-if=\"formErr.errors && formErr.errors.length > 0\" type=\"error\" :message=\"formErr.msg\" :show-icon=\"true\" closable>\n")
	result += fmt.Sprintf("\t\t\t\t<template #description>\n")
	result += fmt.Sprintf("\t\t\t\t\t<span v-for=\"(item, index) in formErr.errors\" :key=\"item\">\n")
	result += fmt.Sprintf("\t\t\t\t\t\t{{ item }}\n")
	result += fmt.Sprintf("\t\t\t\t\t\t<br v-if=\"index < formErr.errors.length - 1\" />\n")
	result += fmt.Sprintf("\t\t\t\t\t</span>\n")
	result += fmt.Sprintf("\t\t\t\t</template>\n")
	result += fmt.Sprintf("\t\t\t</a-alert>\n")
	result += fmt.Sprintf("\t\t\t<div class=\"drawer-bottom-btn\">\n")
	result += fmt.Sprintf("\t\t\t\t<a-button :style=\"{ marginRight: '8px' }\" @click=\"handleCancel\">\n")
	result += fmt.Sprintf("\t\t\t\t\t<template #icon><CloseOutlined /></template>\n")
	result += fmt.Sprintf("\t\t\t\t\t取消\n")
	result += fmt.Sprintf("\t\t\t\t</a-button>\n")
	result += fmt.Sprintf("\t\t\t\t<a-button type=\"primary\" @click=\"handleSubmit\">\n")
	result += fmt.Sprintf("\t\t\t\t\t<template #icon><CheckOutlined /></template>\n")
	result += fmt.Sprintf("\t\t\t\t\t提交\n")
	result += fmt.Sprintf("\t\t\t\t</a-button>\n")
	result += fmt.Sprintf("\t\t\t</div>\n")
	result += fmt.Sprintf("\t\t</a-spin>\n")
	result += fmt.Sprintf("\t</a-drawer>\n")
	result += fmt.Sprintf("</template>\n")
	result += fmt.Sprintf("\n")
	result += fmt.Sprintf("<script>\n")
	result += fmt.Sprintf("import { reactive, ref, inject, toRaw } from 'vue';\n")
	result += fmt.Sprintf("import { Form } from 'ant-design-vue';\n")
	result += fmt.Sprintf("import { CloseOutlined, CheckOutlined } from '@ant-design/icons-vue';\n")
	result += fmt.Sprintf("\n")
	result += fmt.Sprintf("const useForm = Form.useForm;\n")
	result += fmt.Sprintf("export default {\n")
	result += fmt.Sprintf("\tcomponents: { CloseOutlined, CheckOutlined },\n")
	result += fmt.Sprintf("\temits: ['ok'],\n")
	result += fmt.Sprintf("\tsetup(props, context) {\n")
	result += fmt.Sprintf("\t\tconst common = inject('common');\n")
	result += fmt.Sprintf("\t\tconst title = ref('');\n")
	result += fmt.Sprintf("\t\tconst visible = ref(false);\n")
	result += fmt.Sprintf("\t\tconst formErr = ref({});\n")
	result += fmt.Sprintf("\t\tconst formLoading = ref(false);\n")
	result += fmt.Sprintf("\t\tconst defaultForm = reactive({\n")
	result += fmt.Sprintf("\t\t\tid: '',\n")
	result += fmt.Sprintf("\t\t\tXXX: '',\n")
	if ExistRemarkField(cfg) {
		result += fmt.Sprintf("\t\t\tremark: '',\n")
	}
	if ExistStatusField(cfg) {
		result += fmt.Sprintf("\t\t\tstatus: 1,\n")
	}
	result += fmt.Sprintf("\t\t});\n")
	result += fmt.Sprintf("\t\tconst defaultFormRules = reactive({\n")
	result += fmt.Sprintf("\t\t\tXXX: [\n")
	result += fmt.Sprintf("\t\t\t\t{\n")
	result += fmt.Sprintf("\t\t\t\t\trequired: true,\n")
	result += fmt.Sprintf("\t\t\t\t\tmessage: 'XXX不能为空',\n")
	result += fmt.Sprintf("\t\t\t\t},\n")
	result += fmt.Sprintf("\t\t\t\t{\n")
	result += fmt.Sprintf("\t\t\t\t\tmin: 2,\n")
	result += fmt.Sprintf("\t\t\t\t\tmessage: '请输入至少2个字符',\n")
	result += fmt.Sprintf("\t\t\t\t},\n")
	result += fmt.Sprintf("\t\t\t],\n")
	result += fmt.Sprintf("\t\t});\n")
	result += fmt.Sprintf("\t\tconst defaultFormObj = useForm(defaultForm, defaultFormRules, {});\n")
	result += fmt.Sprintf("\n")
	result += fmt.Sprintf("\t\tconst open = dataId => {\n")
	result += fmt.Sprintf("\t\t\tconsole.log(dataId);\n")
	result += fmt.Sprintf("\t\t\tvisible.value = true;\n")
	result += fmt.Sprintf("\t\t\ttitle.value = '新增%s';\n", cfg.TableComment)
	result += fmt.Sprintf("\t\t\tformErr.value = {};\n")
	result += fmt.Sprintf("\t\t\tif (dataId) {\n")
	result += fmt.Sprintf("\t\t\t\ttitle.value = '修改%s';\n", cfg.TableComment)
	result += fmt.Sprintf("\t\t\t\tlet url = process.env.MANAGE_GATEWAY_HOST + '/sys/%s/%s/' + dataId;\n", packageName, SmallHump(cfg.TableName))
	result += fmt.Sprintf("\t\t\t\tcommon.loadFormData(formLoading, defaultFormObj, url);\n")
	result += fmt.Sprintf("\t\t\t} else {\n")
	result += fmt.Sprintf("\t\t\t\tdefaultFormObj.resetFields();\n")
	result += fmt.Sprintf("\t\t\t}\n")
	result += fmt.Sprintf("\t\t};\n")
	result += fmt.Sprintf("\t\tconst handleCancel = () => {\n")
	result += fmt.Sprintf("\t\t\tdefaultFormObj.resetFields();\n")
	result += fmt.Sprintf("\t\t\tvisible.value = false;\n")
	result += fmt.Sprintf("\t\t};\n")
	result += fmt.Sprintf("\t\tconst handleSubmit = () => {\n")
	result += fmt.Sprintf("\t\t\tdefaultFormObj.validate().then(() => {\n")
	result += fmt.Sprintf("\t\t\t\tconsole.log(toRaw(defaultForm));\n")
	result += fmt.Sprintf("\t\t\t\tformLoading.value = true;\n")
	result += fmt.Sprintf("\t\t\t\tlet method = defaultForm.id ? 'put' : 'post';\n")
	result += fmt.Sprintf("\t\t\t\tcommon\n")
	result += fmt.Sprintf("\t\t\t\t\t.api({\n")
	result += fmt.Sprintf("\t\t\t\t\t\turl: process.env.MANAGE_GATEWAY_HOST + '/sys/%s/%s',\n", packageName, SmallHump(cfg.TableName))
	result += fmt.Sprintf("\t\t\t\t\t\tmethod: method,\n")
	result += fmt.Sprintf("\t\t\t\t\t\tdata: toRaw(defaultForm),\n")
	result += fmt.Sprintf("\t\t\t\t\t})\n")
	result += fmt.Sprintf("\t\t\t\t\t.then(response => {\n")
	result += fmt.Sprintf("\t\t\t\t\t\tformLoading.value = false;\n")
	result += fmt.Sprintf("\t\t\t\t\t\tif (response.success) {\n")
	result += fmt.Sprintf("\t\t\t\t\t\t\tcommon.msg.success(response.msg);\n")
	result += fmt.Sprintf("\t\t\t\t\t\t\tdefaultFormObj.resetFields();\n")
	result += fmt.Sprintf("\t\t\t\t\t\t\tvisible.value = false;\n")
	result += fmt.Sprintf("\t\t\t\t\t\t\tcontext.emit('ok');\n")
	result += fmt.Sprintf("\t\t\t\t\t\t} else {\n")
	result += fmt.Sprintf("\t\t\t\t\t\t\tcommon.formErr(response, formErr);\n")
	result += fmt.Sprintf("\t\t\t\t\t\t}\n")
	result += fmt.Sprintf("\t\t\t\t\t})\n")
	result += fmt.Sprintf("\t\t\t\t\t.catch(err => {\n")
	result += fmt.Sprintf("\t\t\t\t\t\tconsole.log(err);\n")
	result += fmt.Sprintf("\t\t\t\t\t\tformLoading.value = false;\n")
	result += fmt.Sprintf("\t\t\t\t\t});\n")
	result += fmt.Sprintf("\t\t\t});\n")
	result += fmt.Sprintf("\t\t};\n")
	result += fmt.Sprintf("\n")
	result += fmt.Sprintf("\t\treturn {\n")
	result += fmt.Sprintf("\t\t\tcommon,\n")
	result += fmt.Sprintf("\t\t\tlabelCol: {\n")
	result += fmt.Sprintf("\t\t\t\txs: { span: 24 },\n")
	result += fmt.Sprintf("\t\t\t\tsm: { span: 4 },\n")
	result += fmt.Sprintf("\t\t\t},\n")
	result += fmt.Sprintf("\t\t\twrapperCol: {\n")
	result += fmt.Sprintf("\t\t\t\txs: { span: 24 },\n")
	result += fmt.Sprintf("\t\t\t\tsm: { span: 20 },\n")
	result += fmt.Sprintf("\t\t\t},\n")
	result += fmt.Sprintf("\t\t\ttitle,\n")
	result += fmt.Sprintf("\t\t\tvisible,\n")
	result += fmt.Sprintf("\t\t\tformErr,\n")
	result += fmt.Sprintf("\t\t\tformLoading,\n")
	result += fmt.Sprintf("\t\t\tdefaultForm,\n")
	result += fmt.Sprintf("\t\t\tdefaultFormObj,\n")
	result += fmt.Sprintf("\t\t\topen,\n")
	result += fmt.Sprintf("\t\t\thandleCancel,\n")
	result += fmt.Sprintf("\t\t\thandleSubmit,\n")
	result += fmt.Sprintf("\t\t};\n")
	result += fmt.Sprintf("\t},\n")
	result += fmt.Sprintf("};\n")
	result += fmt.Sprintf("</script>\n")
	result += fmt.Sprintf("\n")
	result += fmt.Sprintf("<style lang=\"less\"></style>\n")
	result += fmt.Sprintf("\n")
	WriteFile(result, cfg.TargetPath+"/vue/"+packageName, BigHump(cfg.TableName)+"EditForm.vue")
	return result
}

// SmallHump 小驼峰
func SmallHump(str string) string {
	var result = BigHump(str)
	return strings.ToLower(result[:1]) + result[1:]
}

// BigHump 大驼峰
func BigHump(str string) string {
	parts := strings.Split(str, "_")
	for i, part := range parts {
		if len(part) > 0 {
			parts[i] = strings.Title(part)
		}
	}
	return strings.Join(parts, "")
}

// GoLangTypeMapping 数据库类型映射
func GoLangTypeMapping(fileName, dbType string) string {
	if dbType == "varchar" {
		return "string"
	} else if dbType == "tinyint" && fileName == "status" {
		return "enabled.Enabled"
	} else if dbType == "int" {
		return "int"
	} else if dbType == "tinyint" {
		return "int"
	} else if dbType == "bigint" {
		return "int64"
	} else if dbType == "text" {
		return "string"
	} else if dbType == "longtext" {
		return "string"
	} else if dbType == "decimal" {
		return "float32"
	} else if dbType == "json" {
		return "string"
	} else if dbType == "datetime" {
		return "xtime.Time"
	} else {
		return "string"
	}
}

// WriteFile 写文件
func WriteFile(content, path, fileName string) {
	_ = os.MkdirAll(path, 0777)
	file, err := os.Create(path + "/" + fileName)
	if err != nil {
		fmt.Println(err.Error())
	}
	defer func(file *os.File) {
		_ = file.Close()
	}(file)

	_, err = file.WriteString(content)
	if err != nil {
		fmt.Println(err.Error())
	}
}

// ExistStatusField 是否存在可用状态字段
func ExistStatusField(cfg *CodeGenConfig) bool {
	if cfg.StandardTable {
		for _, field := range cfg.Fields {
			if field.FieldName == "status" && field.FieldType == "tinyint" {
				return true
			}
		}
	}
	return false
}

// ExistRemarkField 是否存在备注字段
func ExistRemarkField(cfg *CodeGenConfig) bool {
	if cfg.StandardTable {
		for _, field := range cfg.Fields {
			if field.FieldName == "remark" && field.FieldType == "varchar" {
				return true
			}
		}
	}
	return false
}
